package com.zhuhjay.config;

import com.zhuhjay.security.filter.BasicTokenVerifyFilter;
import com.zhuhjay.security.filter.LoginTokenFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

/**
 * @author ZhuHJay
 * @date 2023/1/11 13:42
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    /** 密码明文加密方式配置 **/
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /** 获取AuthenticationManager（认证管理器），登录时认证使用 **/
    @Bean
    public AuthenticationManager authenticationManager(
            AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }

    /** web资源放行 **/
    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring().antMatchers(
                "/doc.html", "/webjars/**", "/img.icons/**",
                "/swagger-resources/**", "/v2/api-docs", "favicon.ico",
                "/profile/avatar/**", "/profile/upload/**",
                "/user/register");
    }

    /** SpringSecurity5.7 推荐使用 **/
    @Bean
    public SecurityFilterChain filterChain(
            HttpSecurity http, AuthenticationManager authenticationManager,
            UserDetailsService userDetailsService) throws Exception {
        // CSRF禁用，因为不使用session
        http.csrf().disable()
                // 基于token，所以不需要session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .headers().frameOptions().disable();

        http.userDetailsService(userDetailsService)
                // 添加登录过滤器
                .addFilter(new LoginTokenFilter(authenticationManager))
                // 添加token校验过滤器
                .addFilter(new BasicTokenVerifyFilter(authenticationManager))
                // 这一块因为配置了放行不生效，故移动至 web 放行
                .authorizeHttpRequests()
                .anyRequest().authenticated();
        return http.build();
    }

}
